package com.ssy.lingxi.marketing.serviceimpl.base.activity;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.constant.member.MemberRoleEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.common.utils.DateTimeUtil;
import com.ssy.lingxi.marketing.entity.activity.*;
import com.ssy.lingxi.marketing.model.constant.CommonBooleanEnum;
import com.ssy.lingxi.marketing.model.dto.ActivityInnerRecordRespDTO;
import com.ssy.lingxi.marketing.model.dto.ActivityOuterRecordRespDTO;
import com.ssy.lingxi.marketing.model.dto.ActivityRecordPageReqDTO;
import com.ssy.lingxi.marketing.model.vo.activity.request.ActivityInnerRecordPageReq;
import com.ssy.lingxi.marketing.model.vo.activity.request.ActivityOuterRecordPageReq;
import com.ssy.lingxi.marketing.model.vo.activity.response.ActivityInnerRecordResp;
import com.ssy.lingxi.marketing.model.vo.activity.response.ActivityOuterRecordResp;
import com.ssy.lingxi.marketing.model.vo.common.response.TaskStepVO;
import com.ssy.lingxi.marketing.repository.*;
import com.ssy.lingxi.marketing.service.IProcessFeignService;
import com.ssy.lingxi.workflow.api.model.vo.request.ExternalProcessQueryVO;
import com.ssy.lingxi.workflow.api.model.vo.request.InternalProcessQueryVO;
import com.ssy.lingxi.workflow.api.model.vo.response.SimpleProcessDefVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 基础活动记录服务实现类
 * @author yzc
 * @version 2.0.0
 * @date 2021/8/16
 */
@Slf4j
@Service
public class BaseActivityRecordService {

    @Resource
    private PlatformActivityOuterRecordRepository platformOuterRepository;
    @Resource
    private PlatformActivityInnerRecordRepository platformInnerRepository;
    @Resource
    private PlatformActivitySignUpInnerRecordRepository signUpInnerRepository;
    @Resource
    private MerchantActivityOuterRecordRepository merchantOuterRepository;
    @Resource
    private MerchantActivityInnerRecordRepository merchantInnerRepository;
    @Resource
    private PlatformActivitySignUpRepository platformActivitySignUpRepository;
    @Resource
    private IProcessFeignService processFeignService;

    // ========================平台活动内部流转记录========================

    /**
     * 新增平台活动内部流转记录
     * @param loginUser 登录用户信息
     * @param activityId 平台活动id
     * @param status 状态
     * @param statusName 状态名称
     * @param operate 操作
     * @param opinion 意见
     **/
    public void savePlatformActivityInnerRecord(UserLoginCacheDTO loginUser, Long activityId, Integer status, String statusName, String operate, String opinion) {
        PlatformActivityInnerRecordDO recordDO = new PlatformActivityInnerRecordDO();
        recordDO.setActivityId(activityId);
        recordDO.setUserId(loginUser.getUserId());
        recordDO.setMemberId(loginUser.getMemberId());
        recordDO.setRoleId(loginUser.getMemberRoleId());
        recordDO.setOperator(loginUser.getUserName());
        recordDO.setDepartment(loginUser.getUserOrgName());
        recordDO.setJobTitle(loginUser.getUserJobTitle());
        recordDO.setStatus(status);
        recordDO.setStatusName(statusName);
        recordDO.setOperate(operate);
        recordDO.setOperateTime(System.currentTimeMillis());
        recordDO.setOpinion(opinion);
        platformInnerRepository.saveAndFlush(recordDO);
    }

    /**
     * 分页查询平台活动内部流转记录
     * @param loginUser 登录用户信息
     * @param pageVO 分页请求参数
     * @return 操作结果
     **/
    public PageData<ActivityInnerRecordRespDTO> pagePlatformActivityInnerRecordCommon(UserLoginCacheDTO loginUser, ActivityRecordPageReqDTO pageVO) {
        // 组装查询条件
        Specification<PlatformActivityInnerRecordDO> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            if(pageVO.getDataId()!=null) {
                list.add(criteriaBuilder.equal(root.get("activityId").as(Long.class), pageVO.getDataId()));
            }
            if(loginUser!=null) {
                list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), loginUser.getMemberId()));
                list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), loginUser.getMemberRoleId()));
            }
            if(pageVO.getStartTime()!=null){
                list.add(criteriaBuilder.ge(root.get("operateTime").as(Long.class), pageVO.getStartTime()));
            }
            if(pageVO.getEndTime()!=null){
                list.add(criteriaBuilder.le(root.get("operateTime").as(Long.class), pageVO.getEndTime()));
            }
            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        // 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by(pageVO.getSort()? Sort.Direction.ASC:Sort.Direction.DESC,"operateTime"));

        Page<PlatformActivityInnerRecordDO> recordList = platformInnerRepository.findAll(spec, page);
        List<ActivityInnerRecordRespDTO> resultList = recordList.stream().map(r -> {
            ActivityInnerRecordRespDTO entity = new ActivityInnerRecordRespDTO();
            entity.setOperator(r.getOperator());
            entity.setDepartment(r.getDepartment());
            entity.setJobTitle(r.getJobTitle());
            entity.setStatus(r.getStatus());
            entity.setStatusName(r.getStatusName());
            entity.setOperate(r.getOperate());
            entity.setOperateTime(DateUtil.format(DateUtil.date(r.getOperateTime()), "yyyy-MM-dd HH:mm"));
            entity.setOpinion(r.getOpinion());
            entity.setDataId(r.getActivityId());
            return entity;
        }).collect(Collectors.toList());
        return new PageData<>(recordList.getTotalElements(), resultList);
    }

    private ActivityRecordPageReqDTO buildActivityRecordPageReqDTO(ActivityOuterRecordPageReq req){
        ActivityRecordPageReqDTO dto=new ActivityRecordPageReqDTO();
        dto.setDataId(req.getActivityId());
        dto.setPageSize(Constants.DETAIL_LOG_MAX_COUNT);
        return dto;
    }

    private ActivityRecordPageReqDTO buildActivityRecordPageReqDTO(ActivityInnerRecordPageReq req){
        ActivityRecordPageReqDTO dto=new ActivityRecordPageReqDTO();
        dto.setDataId(req.getActivityId());
        dto.setPageSize(Constants.DETAIL_LOG_MAX_COUNT);
        return dto;
    }

    private List<ActivityOuterRecordResp> convertActivityOuterRecordRespList(PageData<ActivityOuterRecordRespDTO> pageData){
        List<ActivityOuterRecordResp> recordResps=null;
        if(CollectionUtil.isNotEmpty(pageData.getData())){
            recordResps = pageData.getData().stream().map(o -> {
                ActivityOuterRecordResp resp = new ActivityOuterRecordResp();
                BeanUtils.copyProperties(o, resp);
                return resp;
            }).collect(Collectors.toList());
        }
        return recordResps;
    }

    private List<ActivityInnerRecordResp> convertActivityInnerRecordRespList(PageData<ActivityInnerRecordRespDTO> pageData){
        List<ActivityInnerRecordResp> recordResps=null;
        if(CollectionUtil.isNotEmpty(pageData.getData())){
            recordResps = pageData.getData().stream().map(o -> {
                ActivityInnerRecordResp resp = new ActivityInnerRecordResp();
                BeanUtils.copyProperties(o, resp);
                return resp;
            }).collect(Collectors.toList());
        }
        return recordResps;
    }

    /**
     * 分页查询平台活动内部流转记录
     * @param loginUser 登录用户信息
     * @param pageVO 分页请求参数
     * @return 操作结果
     **/
    public Wrapper<PageData<ActivityInnerRecordResp>> pagePlatformActivityInnerRecord(UserLoginCacheDTO loginUser, ActivityInnerRecordPageReq pageVO) {
        PageData<ActivityInnerRecordRespDTO> pageData = pagePlatformActivityInnerRecordCommon(loginUser, buildActivityRecordPageReqDTO(pageVO));
        return Wrapper.success(new PageData<>(pageData.getTotalCount(), convertActivityInnerRecordRespList(pageData)));
    }

    /**
     * 查询平台营销活动内部流转记录
     *
     * @param loginUser  登录用户信息
     * @param activityId 平台活动id
     * @return 返回结果
     */
    public List<ActivityInnerRecordResp> getPlatformInnerRecord(UserLoginCacheDTO loginUser, Long activityId) {
        ActivityRecordPageReqDTO dto=new ActivityRecordPageReqDTO();
        dto.setDataId(activityId);
        PageData<ActivityInnerRecordRespDTO> pageData = pagePlatformActivityInnerRecordCommon(loginUser, dto);
        return convertActivityInnerRecordRespList(pageData);
    }

    // ========================平台活动外部流转记录========================

    /**
     * 新增平台活动外部流转记录
     * @param loginUser 登录用户信息
     * @param activityId 平台活动id
     * @param status 状态
     * @param statusName 状态名称
     * @param operate 操作
     * @param opinion 意见
     **/
    public void savePlatformActivityOuterRecord(UserLoginCacheDTO loginUser, Long activityId, Integer status, String statusName, String operate, String opinion) {
        PlatformActivityOuterRecordDO recordDO = new PlatformActivityOuterRecordDO();
        recordDO.setActivityId(activityId);
        recordDO.setUserId(loginUser.getUserId());
        recordDO.setMemberId(loginUser.getMemberId());
        recordDO.setRoleId(loginUser.getMemberRoleId());
        recordDO.setRoleName(loginUser.getMemberRoleName());
        recordDO.setStatus(status);
        recordDO.setStatusName(statusName);
        recordDO.setOperate(operate);
        recordDO.setOperateTime(System.currentTimeMillis());
        recordDO.setOpinion(opinion);
        platformOuterRepository.saveAndFlush(recordDO);
    }

    /**
     * 分页查询平台活动外部流转记录
     * @param loginUser 登录用户信息
     * @param pageVO 分页请求参数
     * @return 操作结果
     **/
    public PageData<ActivityOuterRecordRespDTO> pagePlatformActivityOuterRecordCommon(UserLoginCacheDTO loginUser, ActivityRecordPageReqDTO pageVO) {
        // 组装查询条件
        Specification<PlatformActivityOuterRecordDO> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            if(pageVO.getDataId()!=null){
                list.add(criteriaBuilder.equal(root.get("activityId").as(Long.class), pageVO.getDataId()));
            }
            if(loginUser!=null){
                if (!MemberRoleEnum.PLATFORM.getMemberId().equals(loginUser.getMemberRoleId())) {
                    // 会员查询
                    Predicate predMember = criteriaBuilder.equal(root.get("memberId").as(Long.class), loginUser.getMemberId());
                    Predicate predRole = criteriaBuilder.equal(root.get("roleId").as(Long.class), loginUser.getMemberId());
                    Predicate member = criteriaBuilder.and(predMember, predRole);
                    Predicate predMemberPf = criteriaBuilder.equal(root.get("memberId").as(Long.class), MemberRoleEnum.PLATFORM.getMemberId());
                    Predicate predRolePf = criteriaBuilder.equal(root.get("roleId").as(Long.class), MemberRoleEnum.PLATFORM.getRoleId());
                    Predicate pfMember = criteriaBuilder.and(predMemberPf, predRolePf);
                    list.add(criteriaBuilder.or(member, pfMember));
                } else {
                    // 平台查询
                    list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), loginUser.getMemberId()));
                    list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), loginUser.getMemberRoleId()));
                }
            }
            if(pageVO.getStartTime()!=null){
                list.add(criteriaBuilder.ge(root.get("operateTime").as(Long.class), pageVO.getStartTime()));
            }
            if(pageVO.getEndTime()!=null){
                list.add(criteriaBuilder.le(root.get("operateTime").as(Long.class), pageVO.getEndTime()));
            }
            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };
        // 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by(pageVO.getSort()? Sort.Direction.ASC:Sort.Direction.DESC,"operateTime"));

        Page<PlatformActivityOuterRecordDO> recordList = platformOuterRepository.findAll(spec, page);
        List<ActivityOuterRecordRespDTO> resultList = recordList.stream().map(r -> {
            ActivityOuterRecordRespDTO entity = new ActivityOuterRecordRespDTO();
            entity.setRoleName(r.getRoleName());
            entity.setStatus(r.getStatus());
            entity.setStatusName(r.getStatusName());
            entity.setOperate(r.getOperate());
            entity.setOperateTime(DateUtil.format(DateUtil.date(r.getOperateTime()), "yyyy-MM-dd HH:mm"));
            entity.setOpinion(r.getOpinion());
            entity.setDataId(r.getActivityId());
            return entity;
        }).collect(Collectors.toList());

        return new PageData<>(recordList.getTotalElements(), resultList);
    }

    /**
     * 分页查询平台活动外部流转记录
     * @param loginUser 登录用户信息
     * @param pageVO 分页请求参数
     * @return 操作结果
     **/
    public Wrapper<PageData<ActivityOuterRecordResp>> pagePlatformActivityOuterRecord(UserLoginCacheDTO loginUser, ActivityOuterRecordPageReq pageVO) {
        PageData<ActivityOuterRecordRespDTO> pageData = pagePlatformActivityOuterRecordCommon(loginUser, buildActivityRecordPageReqDTO(pageVO));
        return Wrapper.success(new PageData<>(pageData.getTotalCount(), convertActivityOuterRecordRespList(pageData)));
    }

    /**
     * 查询平台营销活动外部流转记录
     *
     * @param loginUser  登录用户信息
     * @param activityId 平台活动id
     * @return 返回结果
     */
    public List<ActivityOuterRecordResp> getPlatformOuterRecord(UserLoginCacheDTO loginUser, Long activityId) {
        ActivityRecordPageReqDTO req=new ActivityRecordPageReqDTO();
        req.setDataId(activityId);
        PageData<ActivityOuterRecordRespDTO> pageData = pagePlatformActivityOuterRecordCommon(loginUser, req);
        return convertActivityOuterRecordRespList(pageData);
    }

    // ========================平台活动会员报名内部流转记录========================

    /**
     * 新增平台活动报名内部流转记录
     * @param loginUser 登录用户信息
     * @param signUpId 会员报名id
     * @param status 状态
     * @param statusName 状态名称
     * @param operate 操作
     * @param opinion 意见
     */
    public void savePlatformActivitySignUpInnerRecord(UserLoginCacheDTO loginUser, Long activityId, Long signUpId, Integer status, String statusName, String operate, String opinion) {
        PlatformActivitySignUpInnerRecordDO recordDO = new PlatformActivitySignUpInnerRecordDO();
        recordDO.setActivityId(activityId);
        recordDO.setSignUpId(signUpId);
        recordDO.setUserId(loginUser.getUserId());
        recordDO.setMemberId(loginUser.getMemberId());
        recordDO.setRoleId(loginUser.getMemberRoleId());
        recordDO.setOperator(loginUser.getUserName());
        recordDO.setDepartment(loginUser.getUserOrgName());
        recordDO.setJobTitle(loginUser.getUserJobTitle());
        recordDO.setStatus(status);
        recordDO.setStatusName(statusName);
        recordDO.setOperate(operate);
        recordDO.setOperateTime(System.currentTimeMillis());
        recordDO.setOpinion(opinion);
        signUpInnerRepository.saveAndFlush(recordDO);
    }

    /**
     * 分页查询平台活动报名内部流转记录
     * @param loginUser 登录用户信息
     * @param pageVO 分页请求参数
     * @return 操作结果
     **/
    public Wrapper<PageData<ActivityInnerRecordResp>> pagePlatformActivitySignUpInnerRecord(UserLoginCacheDTO loginUser, ActivityInnerRecordPageReq pageVO) {
        // 组装查询条件
        Specification<PlatformActivitySignUpInnerRecordDO> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("activityId").as(Long.class), pageVO.getActivityId()));
            list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), loginUser.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), loginUser.getMemberRoleId()));

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        // 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("operateTime").ascending());

        Page<PlatformActivitySignUpInnerRecordDO> recordList = signUpInnerRepository.findAll(spec, page);
        List<ActivityInnerRecordResp> resultList = recordList.stream().map(r -> {
            ActivityInnerRecordResp entity = new ActivityInnerRecordResp();
            entity.setOperator(r.getOperator());
            entity.setDepartment(r.getDepartment());
            entity.setJobTitle(r.getJobTitle());
            entity.setStatus(r.getStatus());
            entity.setStatusName(r.getStatusName());
            entity.setOperate(r.getOperate());
            entity.setOperateTime(DateUtil.format(DateUtil.date(r.getOperateTime()), "yyyy-MM-dd HH:mm"));
            entity.setOpinion(r.getOpinion());
            return entity;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(recordList.getTotalElements(), resultList));

    }

    /**
     * 查询平台营销活动报名内部流转记录
     *
     * @param loginUser  登录用户信息
     * @param signUpId 活动报名id
     * @return 返回结果
     */
    public List<ActivityInnerRecordResp> getPlatformSignUpInnerRecord(UserLoginCacheDTO loginUser, Long signUpId) {
        Specification<PlatformActivitySignUpInnerRecordDO> innerSpec = (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(cb.equal(root.get("signUpId").as(Long.class), signUpId));
            list.add(cb.equal(root.get("memberId").as(Long.class), loginUser.getMemberId()));
            list.add(cb.equal(root.get("roleId").as(Long.class), loginUser.getMemberRoleId()));

            Predicate[] p = new Predicate[list.size()];
            return cb.and(list.toArray(p));
        };
        List<PlatformActivitySignUpInnerRecordDO> innerRecordDOList = signUpInnerRepository.findAll(innerSpec, Sort.by("operateTime").ascending());
        return innerRecordDOList.stream().map(r -> {
            ActivityInnerRecordResp entity = new ActivityInnerRecordResp();
            entity.setOperator(r.getOperator());
            entity.setDepartment(r.getDepartment());
            entity.setJobTitle(r.getJobTitle());
            entity.setStatus(r.getStatus());
            entity.setStatusName(r.getStatusName());
            entity.setOperate(r.getOperate());
            entity.setOperateTime(DateUtil.format(DateTimeUtil.toLocalDateTime(r.getOperateTime()), "yyyy-MM-dd HH:mm"));
            entity.setOpinion(r.getOpinion());
            return entity;
        }).collect(Collectors.toList());
    }
    // ========================平台活动会员报名外部流转记录========================

    /**
     * 新增平台活动报名外部流转记录
     * @param loginUser 登录用户信息
     * @param activityId 平台活动id
     * @param status 状态
     * @param statusName 状态名称
     * @param operate 操作
     * @param opinion 意见
     **/
    public void savePlatformActivitySignUpOuterRecord(UserLoginCacheDTO loginUser, Long activityId, Long signUpId, Integer status, String statusName, String operate, String opinion) {
        PlatformActivityOuterRecordDO recordDO = new PlatformActivityOuterRecordDO();
        recordDO.setActivityId(activityId);
        recordDO.setSignUpId(signUpId);
        recordDO.setUserId(loginUser.getUserId());
        recordDO.setMemberId(loginUser.getMemberId());
        recordDO.setRoleId(loginUser.getMemberRoleId());
        recordDO.setRoleName(loginUser.getMemberRoleName());
        recordDO.setStatus(status);
        recordDO.setStatusName(statusName);
        recordDO.setOperate(operate);
        recordDO.setOperateTime(System.currentTimeMillis());
        recordDO.setOpinion(opinion);
        platformOuterRepository.saveAndFlush(recordDO);
    }

    /**
     * 分页查询平台活动报名外部流转记录
     * @param loginUser 登录用户信息
     * @param pageVO 分页请求参数
     * @return 操作结果
     **/
    public Wrapper<PageData<ActivityOuterRecordResp>> pagePlatformActivitySignUpOuterRecord(UserLoginCacheDTO loginUser, ActivityOuterRecordPageReq pageVO) {
        // 报名信息
        PlatformActivitySignUpDO signUpDO = platformActivitySignUpRepository.findByPlatformActivityIdAndMemberIdAndRoleId(pageVO.getActivityId(), loginUser.getMemberId(), loginUser.getMemberRoleId());
        if (Objects.isNull(signUpDO)) {
            return Wrapper.success(new PageData<>());
        }

        // 组装查询条件
        Specification<PlatformActivityOuterRecordDO> spec = (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();
            Predicate and = cb.and(cb.equal(root.get("activityId"), pageVO.getActivityId()), cb.isNull(root.get("signUpId")));
            Predicate or = cb.or(and, cb.equal(root.get("signUpId"), signUpDO.getId()));
            list.add(or);

            Predicate[] p = new Predicate[list.size()];
            return cb.and(list.toArray(p));
        };

        // 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("operateTime").ascending());

        Page<PlatformActivityOuterRecordDO> recordList = platformOuterRepository.findAll(spec, page);
        List<ActivityOuterRecordResp> resultList = recordList.stream().map(r -> {
            ActivityOuterRecordResp entity = new ActivityOuterRecordResp();
            entity.setRoleName(r.getRoleName());
            entity.setStatus(r.getStatus());
            entity.setStatusName(r.getStatusName());
            entity.setOperate(r.getOperate());
            entity.setOperateTime(DateUtil.format(DateUtil.date(r.getOperateTime()), "yyyy-MM-dd HH:mm"));
            entity.setOpinion(r.getOpinion());
            return entity;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(recordList.getTotalElements(), resultList));
    }

    /**
     * 查询平台营销活动报名内部流转记录
     *
     * @param loginUser  登录用户信息
     * @param signUpId 活动报名id
     * @return 返回结果
     */
    public List<ActivityOuterRecordResp> getPlatformSignUpOuterRecord(UserLoginCacheDTO loginUser, Long activityId, Long signUpId) {
        Specification<PlatformActivityOuterRecordDO> outerSpec = (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();
            Predicate and = cb.and(cb.equal(root.get("activityId"), activityId), cb.isNull(root.get("signUpId")));
            Predicate or = cb.or(and, cb.equal(root.get("signUpId"), signUpId));
            list.add(or);

            Predicate[] p = new Predicate[list.size()];
            return cb.and(list.toArray(p));
        };
        List<PlatformActivityOuterRecordDO> outerRecordDOList = platformOuterRepository.findAll(outerSpec, Sort.by("operateTime").ascending());
        return outerRecordDOList.stream().map(r -> {
            ActivityOuterRecordResp entity = new ActivityOuterRecordResp();
            entity.setRoleName(r.getRoleName());
            entity.setStatus(r.getStatus());
            entity.setStatusName(r.getStatusName());
            entity.setOperate(r.getOperate());
            entity.setOperateTime(DateUtil.format(DateUtil.date(r.getOperateTime()), "yyyy-MM-dd HH:mm"));
            entity.setOpinion(r.getOpinion());
            return entity;
        }).collect(Collectors.toList());
    }
    // ========================商家活动内部流转记录========================

    /**
     * 新增商家活动内部流转记录
     * @param loginUser 登录用户信息
     * @param activityId 平台活动id
     * @param status 状态
     * @param statusName 状态名称
     * @param operate 操作
     * @param opinion 意见
     **/
    public void saveMerchantActivityInnerRecord(UserLoginCacheDTO loginUser, Long activityId, Integer status, String statusName, String operate, String opinion) {
        MerchantActivityInnerRecordDO recordDO = new MerchantActivityInnerRecordDO();
        recordDO.setActivityId(activityId);
        recordDO.setUserId(loginUser.getUserId());
        recordDO.setMemberId(loginUser.getMemberId());
        recordDO.setRoleId(loginUser.getMemberRoleId());
        recordDO.setOperator(loginUser.getUserName());
        recordDO.setDepartment(loginUser.getUserOrgName());
        recordDO.setJobTitle(loginUser.getUserJobTitle());
        recordDO.setStatus(status);
        recordDO.setStatusName(statusName);
        recordDO.setOperate(operate);
        recordDO.setOperateTime(System.currentTimeMillis());
        recordDO.setOpinion(opinion);
        merchantInnerRepository.saveAndFlush(recordDO);
    }

    /**
     * 分页查询商家活动内部流转记录
     * @param loginUser 登录用户信息
     * @param pageVO 分页请求参数
     * @return 操作结果
     **/
    public PageData<ActivityInnerRecordRespDTO> pageMerchantActivityInnerRecordCommon(UserLoginCacheDTO loginUser, ActivityRecordPageReqDTO pageVO) {
        // 组装查询条件
        Specification<MerchantActivityInnerRecordDO> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            if(pageVO.getDataId()!=null) {
                list.add(criteriaBuilder.equal(root.get("activityId").as(Long.class), pageVO.getDataId()));
            }
            if(loginUser!=null) {
                list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), loginUser.getMemberId()));
                list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), loginUser.getMemberRoleId()));
            }
            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        // 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by(pageVO.getSort()? Sort.Direction.ASC:Sort.Direction.DESC,"operateTime"));

        Page<MerchantActivityInnerRecordDO> recordList = merchantInnerRepository.findAll(spec, page);
        List<ActivityInnerRecordRespDTO> resultList = recordList.stream().map(r -> {
            ActivityInnerRecordRespDTO entity = new ActivityInnerRecordRespDTO();
            entity.setOperator(r.getOperator());
            entity.setDepartment(r.getDepartment());
            entity.setJobTitle(r.getJobTitle());
            entity.setStatus(r.getStatus());
            entity.setStatusName(r.getStatusName());
            entity.setOperate(r.getOperate());
            entity.setOperateTime(DateUtil.format(DateUtil.date(r.getOperateTime()), "yyyy-MM-dd HH:mm"));
            entity.setOpinion(r.getOpinion());
            return entity;
        }).collect(Collectors.toList());

        return new PageData<>(recordList.getTotalElements(), resultList);
    }

    /**
     * 分页查询商家活动内部流转记录
     * @param loginUser 登录用户信息
     * @param pageVO 分页请求参数
     * @return 操作结果
     **/
    public Wrapper<PageData<ActivityInnerRecordResp>> pageMerchantActivityInnerRecord(UserLoginCacheDTO loginUser, ActivityInnerRecordPageReq pageVO) {
        PageData<ActivityInnerRecordRespDTO> pageData = pageMerchantActivityInnerRecordCommon(loginUser, buildActivityRecordPageReqDTO(pageVO));
        return Wrapper.success(new PageData<>(pageData.getTotalCount(),convertActivityInnerRecordRespList(pageData)));
    }

    /**
     * 查询商家营销活动内部流转记录
     *
     * @param loginUser  登录用户信息
     * @param activityId 平台活动id
     * @return 返回结果
     */
    public List<ActivityInnerRecordResp> getMerchantInnerRecord(UserLoginCacheDTO loginUser, Long activityId) {
        Specification<MerchantActivityInnerRecordDO> innerSpec = (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(cb.equal(root.get("activityId").as(Long.class), activityId));
            list.add(cb.equal(root.get("memberId").as(Long.class), loginUser.getMemberId()));
            list.add(cb.equal(root.get("roleId").as(Long.class), loginUser.getMemberRoleId()));

            Predicate[] p = new Predicate[list.size()];
            return cb.and(list.toArray(p));
        };
        List<MerchantActivityInnerRecordDO> innerRecordDOList = merchantInnerRepository.findAll(innerSpec, Sort.by("operateTime").ascending());
        return innerRecordDOList.stream().map(r -> {
            ActivityInnerRecordResp entity = new ActivityInnerRecordResp();
            entity.setOperator(r.getOperator());
            entity.setDepartment(r.getDepartment());
            entity.setJobTitle(r.getJobTitle());
            entity.setStatus(r.getStatus());
            entity.setStatusName(r.getStatusName());
            entity.setOperate(r.getOperate());
            entity.setOperateTime(DateUtil.format(DateUtil.date(r.getOperateTime()), "yyyy-MM-dd HH:mm"));
            entity.setOpinion(r.getOpinion());
            return entity;
        }).collect(Collectors.toList());
    }

    // ========================商家活动外部部流转记录========================

    /**
     * 新增平台活动外部流转记录
     * @param loginUser 登录用户信息
     * @param activityId 平台活动id
     * @param status 状态
     * @param statusName 状态名称
     * @param operate 操作
     * @param opinion 意见
     **/
    public void saveMerchantActivityOuterRecord(UserLoginCacheDTO loginUser, Long activityId, Integer status, String statusName, String operate, String opinion) {
        MerchantActivityOuterRecordDO recordDO = new MerchantActivityOuterRecordDO();
        recordDO.setActivityId(activityId);
        recordDO.setUserId(loginUser.getUserId());
        recordDO.setMemberId(loginUser.getMemberId());
        recordDO.setRoleId(loginUser.getMemberRoleId());
        recordDO.setRoleName(loginUser.getMemberRoleName());
        recordDO.setStatus(status);
        recordDO.setStatusName(statusName);
        recordDO.setOperate(operate);
        recordDO.setOperateTime(System.currentTimeMillis());
        recordDO.setOpinion(opinion);
        merchantOuterRepository.saveAndFlush(recordDO);
    }

    /**
     * 分页查询-商户活动外部流转记录
     * @param loginUser 登录用户信息
     * @param pageVO 分页请求参数
     * @return 操作结果
     **/
    public PageData<ActivityOuterRecordRespDTO> pageMerchantActivityOuterRecordCommon(UserLoginCacheDTO loginUser, ActivityRecordPageReqDTO pageVO) {
        // 组装查询条件
        Specification<MerchantActivityOuterRecordDO> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            if(pageVO.getDataId()!=null){
                list.add(criteriaBuilder.equal(root.get("activityId").as(Long.class), pageVO.getDataId()));
            }
            if(loginUser!=null){
                if (!MemberRoleEnum.PLATFORM.getMemberId().equals(loginUser.getMemberRoleId())) {
                    // 会员查询
                    Predicate predMember = criteriaBuilder.equal(root.get("memberId").as(Long.class), loginUser.getMemberId());
                    Predicate predRole = criteriaBuilder.equal(root.get("roleId").as(Long.class), loginUser.getMemberId());
                    Predicate member = criteriaBuilder.and(predMember, predRole);
                    Predicate predMemberPf = criteriaBuilder.equal(root.get("memberId").as(Long.class), MemberRoleEnum.PLATFORM.getMemberId());
                    Predicate predRolePf = criteriaBuilder.equal(root.get("roleId").as(Long.class), MemberRoleEnum.PLATFORM.getRoleId());
                    Predicate pfMember = criteriaBuilder.and(predMemberPf, predRolePf);
                    list.add(criteriaBuilder.or(member, pfMember));
                } else {
                    // 平台查询
                    list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), loginUser.getMemberId()));
                    list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), loginUser.getMemberRoleId()));
                }
            }
            if(pageVO.getStartTime()!=null){
                list.add(criteriaBuilder.ge(root.get("operateTime").as(Long.class), pageVO.getStartTime()));
            }
            if(pageVO.getEndTime()!=null){
                list.add(criteriaBuilder.le(root.get("operateTime").as(Long.class), pageVO.getEndTime()));
            }
            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        // 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by(pageVO.getSort()? Sort.Direction.ASC:Sort.Direction.DESC,"operateTime"));

        Page<MerchantActivityOuterRecordDO> recordList = merchantOuterRepository.findAll(spec, page);
        List<ActivityOuterRecordRespDTO> resultList = recordList.stream().map(r -> {
            ActivityOuterRecordRespDTO entity = new ActivityOuterRecordRespDTO();
            entity.setRoleName(r.getRoleName());
            entity.setStatus(r.getStatus());
            entity.setStatusName(r.getStatusName());
            entity.setOperate(r.getOperate());
            entity.setOperateTime(DateUtil.format(DateUtil.date(r.getOperateTime()), "yyyy-MM-dd HH:mm"));
            entity.setOpinion(r.getOpinion());
            entity.setDataId(r.getActivityId());
            return entity;
        }).collect(Collectors.toList());

        return new PageData<>(recordList.getTotalElements(), resultList);
    }

    /**
     * 分页查询平台活动外部流转记录
     * @param loginUser 登录用户信息
     * @param pageVO 分页请求参数
     * @return 操作结果
     **/
    public Wrapper<PageData<ActivityOuterRecordResp>> pageMerchantActivityOuterRecord(UserLoginCacheDTO loginUser, ActivityOuterRecordPageReq pageVO) {
        PageData<ActivityOuterRecordRespDTO> pageData= pageMerchantActivityOuterRecordCommon(loginUser, buildActivityRecordPageReqDTO(pageVO));
        return Wrapper.success(new PageData<>(pageData.getTotalCount(),convertActivityOuterRecordRespList(pageData)));
    }

    /**
     * 查询商家营销活动外部流转记录
     *
     * @param loginUser  登录用户信息
     * @param activityId 平台活动id
     * @return 返回结果
     */
    public List<ActivityOuterRecordResp> getMerchantOuterRecord(UserLoginCacheDTO loginUser, Long activityId) {
        ActivityRecordPageReqDTO req=new ActivityRecordPageReqDTO();
        req.setDataId(activityId);
        PageData<ActivityOuterRecordRespDTO> pageDataWrapper = pageMerchantActivityOuterRecordCommon(loginUser, req);
        return convertActivityOuterRecordRespList(pageDataWrapper);
    }

    // ==========================活动流转流程==========================

    /**
     * 查询外部流转流程
     *
     * @param processKey 工作流key
     * @param taskId     工作流任务id
     * @return 返回结果
     */
    public List<TaskStepVO> listOuterTask(String processKey, String taskId) {
        ExternalProcessQueryVO externalProcessQueryVO = new ExternalProcessQueryVO();
        externalProcessQueryVO.setProcessKey(processKey);
        externalProcessQueryVO.setTaskId(taskId);
        Wrapper<SimpleProcessDefVO> outerWrapper = processFeignService.findSimpleExternalTaskDefinitions(externalProcessQueryVO);
        if (ResponseCode.SUCCESS.getCode() != outerWrapper.getCode()) {
            log.error("工作流服务异常:" + outerWrapper.getMessage());
            throw new BusinessException(ResponseCode.ENHANCE_WORKFLOW_ERROR);
        }

        // 封装外部工作流程
        List<TaskStepVO> outerTaskList = outerWrapper.getData().getTasks().stream().map(a -> {
            TaskStepVO taskStepVO = new TaskStepVO();
            taskStepVO.setStep(a.getTaskStep());
            taskStepVO.setRoleName(a.getRoleName());
            taskStepVO.setTaskName(a.getTaskName());
            if (outerWrapper.getData().getCurrentStep() == 0 || outerWrapper.getData().getCurrentStep() >= a.getTaskStep()) {
                taskStepVO.setIsExecute(CommonBooleanEnum.YES.getCode());
            } else {
                taskStepVO.setIsExecute(CommonBooleanEnum.NO.getCode());
            }
            return taskStepVO;
        }).collect(Collectors.toList());

        return outerTaskList;
    }

    /**
     * 查询内部流转流程
     *
     * @param processKey 工作流key
     * @param taskId     工作流任务id
     * @return 返回结果
     */
    public List<TaskStepVO> listInnerTask(String processKey, String taskId) {
        InternalProcessQueryVO internalProcessQueryVO = new InternalProcessQueryVO();
        internalProcessQueryVO.setProcessKey(processKey);
        internalProcessQueryVO.setTaskId(taskId);
        Wrapper<SimpleProcessDefVO> innerWrapper = processFeignService.findSimpleInternalTaskDefinitions(internalProcessQueryVO);
        if (ResponseCode.SUCCESS.getCode() != innerWrapper.getCode()) {
            log.error("工作流服务异常:" + innerWrapper.getMessage());
            throw new BusinessException(ResponseCode.ENHANCE_WORKFLOW_ERROR);
        }

        // 封装内部工作流程
        List<TaskStepVO> innerTaskList = innerWrapper.getData().getTasks().stream().map(a -> {
            TaskStepVO taskStepVO = new TaskStepVO();
            taskStepVO.setStep(a.getTaskStep());
            taskStepVO.setRoleName(a.getRoleName());
            taskStepVO.setTaskName(a.getTaskName());
            if (innerWrapper.getData().getCurrentStep() == 0 || innerWrapper.getData().getCurrentStep() >= a.getTaskStep()) {
                taskStepVO.setIsExecute(CommonBooleanEnum.YES.getCode());
            } else {
                taskStepVO.setIsExecute(CommonBooleanEnum.NO.getCode());
            }
            return taskStepVO;
        }).collect(Collectors.toList());

        return innerTaskList;
    }
}